package com.polaris.live.utils.photo

import android.animation.Animator
import android.animation.ValueAnimator
import android.content.pm.ActivityInfo
import android.os.Build
import android.os.Build.VERSION
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.widget.RelativeLayout
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager.OnPageChangeListener
import com.bumptech.glide.GenericTransitionOptions
import com.bumptech.glide.Glide
import com.gyf.immersionbar.ImmersionBar
import com.polaris.live.common.constant.AppConst
import com.polaris.live.common.ext.setOnSingleClickListener
import com.polaris.live.common.mvvm.base2.BaseVbActivity
import com.polaris.live.common.util.NavigationBarUtils
import com.polaris.live.databinding.ActivityDragPhotoBinding
import com.polaris.live.databinding.ItemViewpagerBinding
import com.polaris.live.resp.back_resp.InfoOtherResp
import com.polaris.live.utils.getIntOrString
import com.polaris.live.utils.image.loadImage
import com.polaris.live.utils.image.normal
import com.polaris.live.viewmodel.message.MessageViewModel
import com.polaris.live.widget.avatar.FrameImageUtils
import com.polaris.live.widget.country.countryIcons

/**
 * DragPhotoActivity
 * @author Created by 天晴 on 2024/1/15 9:43
 * @since 1.0.0
 */
class DragPhotoActivity : BaseVbActivity<MessageViewModel, ActivityDragPhotoBinding>() {

    private val mList: MutableList<String> by lazy {
        intent.getStringArrayListExtra("list")?.toMutableList() ?: mutableListOf()
    }
    private var index: Int = 0

    private val user: InfoOtherResp? by lazy {
        if (VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            intent.getParcelableExtra("userInfo", InfoOtherResp::class.java)
        } else {
            intent.getParcelableExtra("userInfo")
        }
    }
    private var mPhotoViews: Array<DragPhotoView> = emptyArray()
    private var mOriginLeft = 0
    private var mOriginTop = 0
    private var mOriginHeight = 0
    private var mOriginWidth = 0
    private var mOriginCenterX = 0
    private var mOriginCenterY = 0
    private var mTargetHeight = 0f
    private var mTargetWidth = 0f
    private var mScaleX = 0f
    private var mScaleY = 0f
    private var mTranslationX = 0f
    private var mTranslationY = 0f

    override fun initImmersionBar() {
        ImmersionBar.with(this)
            .transparentBar()
            .titleBarMarginTop(mBinding.flTouchView)
            .init()

        NavigationBarUtils.setNavigationHeight(mBinding.flTouchView)
    }

    override fun initView(savedInstanceState: Bundle?) {
        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED  //设置屏幕方向

        index = intent.getIntOrString("index", 0)
        user?.let {
            mBinding.avatar.setImageUrl(it.avatar)
            mBinding.avFv.setFrameImage(FrameImageUtils.urlToFrameImageBean(it.decoration?.avatarFrame))
            mBinding.tvNickname.text = it.nickname
            val countryIcon = countryIcons[it.profile.country]
            if (countryIcon == null) {
                mBinding.ivIcon.visibility = RelativeLayout.GONE
            } else {
                mBinding.ivIcon.visibility = RelativeLayout.VISIBLE
                mBinding.ivIcon.setImageResource(countryIcon)
            }
            mBinding.vipView.setVipLevel(it.profile.vipLevel)
            mBinding.rich.setRichCharmBySexLevel(
                AppConst.UserSex.MAN,
                it.account.richs,
                it.account.charms
            )
            mBinding.charm.setRichCharmBySexLevel(
                AppConst.UserSex.WOMAN,
                it.account.richs,
                it.account.charms
            )
        }
        if (mList.size > 1) {
            mBinding.tvIndicator.visibility = View.VISIBLE
            mBinding.tvIndicator.text = "${index + 1}/${mList.size}"
        }

        mBinding.ivBack.setOnSingleClickListener {
            finishWithAnimation()
        }
        mPhotoViews = Array(mList.size) {
            ItemViewpagerBinding.inflate(LayoutInflater.from(this)).root
        }
        for (i in mPhotoViews.indices) {
            Glide.with(this)
                .loadImage(mList[i])
                .transition(GenericTransitionOptions.withNoTransition())
                .normal()
                .into(mPhotoViews[i])
            mPhotoViews[i].setOnExitListener(object : DragPhotoView.OnExitListener {
                override fun onExit(view: DragPhotoView?, x: Float, y: Float, w: Float, h: Float) {
                    performExitAnimation(view, x, y, w, h)
                }
            })
            mPhotoViews[i].setOnActionMoveListener(object : DragPhotoView.OnActionMoveListener {
                override fun Move(p: Boolean) {
                    if (p) {
                        hideTip()
                    } else {
                        showTip()
                    }
                }
            })
        }
        mBinding.viewpager.adapter = object : PagerAdapter() {
            override fun getCount(): Int {
                return mList.size
            }

            override fun instantiateItem(container: ViewGroup, position: Int): Any {
                container.addView(mPhotoViews[position])
                return mPhotoViews[position]
            }

            override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
                container.removeView(mPhotoViews[position])
            }

            override fun isViewFromObject(view: View, `object`: Any): Boolean {
                return view === `object`
            }
        }
        mBinding.viewpager.addOnPageChangeListener(object : OnPageChangeListener {
            override fun onPageScrolled(
                position: Int,
                positionOffset: Float,
                positionOffsetPixels: Int
            ) {
            }

            override fun onPageSelected(position: Int) {
                index = position
                mBinding.tvIndicator.text = "${index + 1}/${mList.size}"
            }

            override fun onPageScrollStateChanged(state: Int) {
            }

        })
        mBinding.viewpager.currentItem = index

        mBinding.viewpager.viewTreeObserver
            .addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
                override fun onGlobalLayout() {
                    mBinding.viewpager.viewTreeObserver.removeOnGlobalLayoutListener(this)
                    mOriginLeft = intent.getIntOrString("left", 0)
                    mOriginTop = intent.getIntOrString("top", 0)
                    mOriginHeight = intent.getIntOrString("height", 0)
                    mOriginWidth = intent.getIntOrString("width", 0)
                    mOriginCenterX = mOriginLeft + mOriginWidth / 2
                    mOriginCenterY = mOriginTop + mOriginHeight / 2
                    val location = IntArray(2)
                    val photoView = mPhotoViews[index]
                    photoView.getLocationOnScreen(location)
                    mTargetHeight = photoView.height.toFloat()
                    mTargetWidth = photoView.width.toFloat()
                    mScaleX = mOriginWidth.toFloat() / mTargetWidth
                    mScaleY = mOriginHeight.toFloat() / mTargetHeight
                    val targetCenterX = location[0] + mTargetWidth / 2
                    val targetCenterY = location[1] + mTargetHeight / 2
                    mTranslationX = mOriginCenterX - targetCenterX
                    mTranslationY = mOriginCenterY - targetCenterY
                    photoView.translationX = mTranslationX
                    photoView.translationY = mTranslationY
                    photoView.scaleX = mScaleX
                    photoView.scaleY = mScaleY
                    performEnterAnimation()
                    for (i in mPhotoViews.indices) {
                        mPhotoViews[i].setMinScale(mScaleX)
                    }
                }
            })
    }

    private fun performExitAnimation(view: DragPhotoView?, x: Float, y: Float, w: Float, h: Float) {
        if (view == null) return

        view.finishAnimationCallBack()
        val animatorAlpha = ValueAnimator.ofInt(255, 0)
        animatorAlpha.duration = FINISHTIME
        animatorAlpha.addUpdateListener { valueAnimator ->
            mPhotoViews[index].setBgAlpha(0)
            mPhotoViews[index].alpha = (valueAnimator.animatedValue as Int) / 255F
        }
        animatorAlpha.start()
        val viewX = mTargetWidth / 2 + x - mTargetWidth * mScaleX / 2
        val viewY = mTargetHeight / 2 + y - mTargetHeight * mScaleY / 2
        view.x = viewX
        view.y = viewY
        val centerX = view.x + mOriginWidth / 2
        val centerY = view.y + mOriginHeight / 2
        val translateX = mOriginCenterX - centerX
        val translateY = mOriginCenterY - centerY
        val translateXAnimator = ValueAnimator.ofFloat(view.x, view.x + translateX)
        translateXAnimator.addUpdateListener { valueAnimator ->
            view.x = (valueAnimator.animatedValue as Float)
        }
        translateXAnimator.duration = FINISHTIME
        translateXAnimator.start()
        val translateYAnimator = ValueAnimator.ofFloat(view.y, view.y + translateY)
        translateYAnimator.addUpdateListener { valueAnimator ->
            view.y = (valueAnimator.animatedValue as Float)
        }
        translateYAnimator.addListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(animator: Animator) {}
            override fun onAnimationEnd(animator: Animator) {
                animator.removeAllListeners()
                finish()
                overridePendingTransition(0, 0)
            }

            override fun onAnimationCancel(animator: Animator) {}
            override fun onAnimationRepeat(animator: Animator) {}
        })
        translateYAnimator.duration = FINISHTIME
        translateYAnimator.start()
    }

    private fun finishWithAnimation() {
        mBinding.flTouchView.visibility = View.GONE
        val animatorAlpha = ValueAnimator.ofInt(255, 0)
        animatorAlpha.duration = FINISHTIME
        animatorAlpha.addUpdateListener { valueAnimator ->
            mBinding.vBg.alpha = (valueAnimator.animatedValue as Int) / 255F
            mPhotoViews[index].setBgAlpha(0)
            mPhotoViews[index].alpha = (valueAnimator.animatedValue as Int) / 255F
        }
        animatorAlpha.start()
        val photoView = mPhotoViews[index]
        val translateXAnimator = ValueAnimator.ofFloat(0f, mTranslationX)
        translateXAnimator.addUpdateListener { valueAnimator ->
            photoView.x = (valueAnimator.animatedValue as Float)
        }
        translateXAnimator.duration = FINISHTIME
        translateXAnimator.start()
        val translateYAnimator = ValueAnimator.ofFloat(0f, mTranslationY)
        translateYAnimator.addUpdateListener { valueAnimator ->
            photoView.y = (valueAnimator.animatedValue as Float)
        }
        translateYAnimator.duration = FINISHTIME
        translateYAnimator.start()
        val scaleYAnimator = ValueAnimator.ofFloat(1f, mScaleY)
        scaleYAnimator.addUpdateListener { valueAnimator ->
            photoView.scaleY = (valueAnimator.animatedValue as Float)
        }
        scaleYAnimator.duration = FINISHTIME
        scaleYAnimator.start()
        val scaleXAnimator = ValueAnimator.ofFloat(1f, mScaleX)
        scaleXAnimator.addUpdateListener { valueAnimator ->
            photoView.scaleX = (valueAnimator.animatedValue as Float)
        }
        scaleXAnimator.addListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(animator: Animator) {}
            override fun onAnimationEnd(animator: Animator) {
                animator.removeAllListeners()
                finish()
                overridePendingTransition(0, 0)
            }

            override fun onAnimationCancel(animator: Animator) {}
            override fun onAnimationRepeat(animator: Animator) {}
        })
        scaleXAnimator.duration = FINISHTIME
        scaleXAnimator.start()
    }

    private fun performEnterAnimation() {
        val animatorAlpha = ValueAnimator.ofInt(0, 255)
        animatorAlpha.duration = FINISHTIME
        animatorAlpha.addUpdateListener { valueAnimator ->
            mBinding.vBg.alpha = (valueAnimator.animatedValue as Int) / 255F
            mPhotoViews[index].setBgAlpha((valueAnimator.animatedValue as Int))
            mPhotoViews[index].alpha = (valueAnimator.animatedValue as Int) / 255F
        }
        animatorAlpha.start()

        val photoView = mPhotoViews[index]
        val translateXAnimator = ValueAnimator.ofFloat(photoView.x, 0f)
        translateXAnimator.addUpdateListener { valueAnimator ->
            photoView.x = (valueAnimator.animatedValue as Float)
        }
        translateXAnimator.duration = ENTERTIME
        translateXAnimator.start()
        val translateYAnimator = ValueAnimator.ofFloat(photoView.y, 0f)
        translateYAnimator.addUpdateListener { valueAnimator ->
            photoView.y = (valueAnimator.animatedValue as Float)
        }
        translateYAnimator.duration = ENTERTIME
        translateYAnimator.start()
        val scaleYAnimator = ValueAnimator.ofFloat(mScaleY, 1f)
        scaleYAnimator.addUpdateListener { valueAnimator ->
            photoView.scaleY = (valueAnimator.animatedValue as Float)
        }
        scaleYAnimator.duration = ENTERTIME
        scaleYAnimator.start()
        val scaleXAnimator = ValueAnimator.ofFloat(mScaleX, 1f)
        scaleXAnimator.addUpdateListener { valueAnimator ->
            photoView.scaleX = (valueAnimator.animatedValue as Float)
        }
        scaleXAnimator.duration = ENTERTIME

        scaleXAnimator.addListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(animator: Animator) {}
            override fun onAnimationEnd(animator: Animator) {
                mBinding.flTouchView.visibility = View.VISIBLE
            }

            override fun onAnimationCancel(animator: Animator) {}
            override fun onAnimationRepeat(animator: Animator) {}
        })
        scaleXAnimator.start()
    }

    fun showTip() {
        mBinding.vBg.visibility = View.VISIBLE
        mBinding.flTouchView.visibility = View.VISIBLE
    }

    fun hideTip() {
        mBinding.vBg.visibility = View.GONE
        mBinding.flTouchView.visibility = View.GONE
    }

    override fun onBackPressed() {
        finishWithAnimation()
    }

    companion object {

        const val ENTERTIME: Long = 300
        const val FINISHTIME: Long = 300
    }

}